/*
 * @Author: January
 * @Date: 2022-01-03 21:22:00
 */

#include <libecc/cipher/cipher_algs.h>
#include <libecc/cipher/cipher_mode.h>

// block_size
void cbc_encrypt(u8* nonce, int block_size, void* cipher_ctx, _block_cipher cipher_enc, const uint8_t* in, int in_len,uint8_t* out) {
    int i = in_len / block_size;
    int j;
    int words = block_size / 4;
    uint32_t* tmp_p4 = (uint32_t*)nonce;
    uint32_t* in_p4;
    uint32_t* out_p4;

    for(;i>0;i--) {
        in_p4 = (uint32_t*)in;
        out_p4 = (uint32_t*)out;
        for (j=0; j<words; j++) {
            out_p4[j] = in_p4[j] ^ tmp_p4[j];
        }
        cipher_enc(cipher_ctx, out, nonce);
        local_memcpy(out, nonce, block_size);
        in += block_size;
        out += block_size;
    }
}

void cbc_decrypt(u8* nonce, int block_size, void* cipher_ctx, _block_cipher cipher_dec, const uint8_t* in, int in_len,uint8_t* out) {
    int i = in_len / block_size;
    int j;
    int words = block_size / 4;
    uint32_t* tmp_p4 = (uint32_t*)nonce;
    uint32_t* out_p4;

    for(;i>0;i--) {
        cipher_dec(cipher_ctx, in, out);
        out_p4 = (uint32_t*)out;
        for (j=0; j<words; j++) {
            out_p4[j] ^= tmp_p4[j];
        }
        local_memcpy(nonce, in, block_size);
        in += block_size;
        out += block_size;
    }
}
